package com.summer.bilibili.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;

import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TimeZone;

/**
 * JSON工具类
 */
@Slf4j
public class JsonUtils {
    public static final ObjectMapper objectMapper = new ObjectMapper ( );

    static {
        //  配置1：忽略JSON中存在但Java对象不存在的字段
        objectMapper.configure ( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES , false );
        // 配置2：统一日期格式与时区
        objectMapper.setDateFormat ( new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) );
        objectMapper.setTimeZone ( TimeZone.getTimeZone ( "Asia/Shanghai" ) );
        // 配置3：序列化时忽略null值字段
        objectMapper.setDefaultPropertyInclusion ( JsonInclude.Include.NON_NULL );//值为null的字段不参与序列化
    }

    /**
     * 从JSON路径读取数据并转换为指定类型
     *
     * @param json  原始JSON字符串
     * @param type  目标类型引用（支持泛型）
     * @param paths JSON路径（如：["data","user"]）
     * @return 目标对象（路径不存在时返回null）
     */
    @Nullable
    public static < T > T readPath ( String json , TypeReference < T > type , String... paths ) {
        try {
            JsonNode node = objectMapper.readTree ( json ); // 构建JSON树
            for ( String path : paths ) {                   // 主机导航
                if ( node.hasNonNull ( path ) ) {           // 校验路径有效性
                    node = node.get ( path );               // 进入下一节点
                } else {
                    return null;
                }
            }
            return objectMapper.readValue ( node.toString ( ) , type ); // 终节点反序列化
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 反序列化为有序Map（保持JSON字段顺序）
     *
     * @param json 原始JSON字符串
     * @return LinkedHashMap实例（解析失败返回null）
     */
    @Nullable
    public static LinkedHashMap < String, Object > readMap ( String json ) {
        try {
            return objectMapper.readValue ( json , new TypeReference < LinkedHashMap < String, Object > > ( ) {
            } );
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 反序列化为对象列表
     *
     * @param json 原始JSON字符串
     * @param type 列表元素类型
     * @return 对象列表（解析失败返回null）
     */
    @Nullable
    public static < T > List < T > readList ( String json , Class < T > type ) {
        try {
            return objectMapper.readValue ( json ,
                    new TypeReference < List < T > > ( ) {} );// 保留泛型信息
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 解析为JsonNode树形结构
     *
     * @param json 原始JSON字符串
     * @return JsonNode节点（含完整结构信息）
     */
    @Nullable
    public static JsonNode readTree ( String json ) {
        try {
            return objectMapper.readTree ( json );
        } catch (Exception e) {
            log.error ( "err: {} json: {}" , e.getMessage ( ) , json );
            e.printStackTrace ( );
            return null;
        }
    }
    // 以下为多数据源反序列化方法组（统一返回null的@Nullable注解）

    /**
     * 从字符串反序列化POJO
     */
    @Nullable
    public static < T > T read ( String json , Class < T > type ) {
        try {
            return objectMapper.readValue ( json , type );
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 从URL资源反序列化POJO
     */
    @Nullable
    public static < T > T read ( URL url , Class < T > type ) {
        try {
            return objectMapper.readValue ( url , type );
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 从输入流反序列化POJO
     */
    @Nullable
    public static < T > T read ( InputStream is , Class < T > type ) {
        try {
            return objectMapper.readValue ( is , type );
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 从字节数组反序列化POJO
     */
    @Nullable
    public static < T > T read ( byte[] data , Class < T > type ) {
        try {
            return objectMapper.readValue ( data , type );
        } catch (Exception e) {
            e.printStackTrace ( );
            return null;
        }
    }

    /**
     * 序列化对象为JSON字符串
     * 注意：仅支持基础POJO，含InputStream等特殊字段的对象会抛出异常
     *
     * @param obj 待序列化对象
     * @return JSON字符串（异常时返回null并记录日志）
     */
    public static String writeString ( Object obj ) {
        try {
            return objectMapper.writeValueAsString ( obj );
        } catch (Exception e) {
            log.error ( "err: {} obj: {}" , e.getMessage ( ) , obj );
            e.printStackTrace ( );
            return null;
        }
    }
}
